#ifndef MODBUSFACTORY_H
#define MODBUSFACTORY_H

#include <QObject>
#include "comstruct.h"

class CModbusFactory
{

public:
	CModbusFactory();
	~CModbusFactory();

public:
	// BA
	int prepareDatagram(int iIndexStep, char* pSendDataBuf, uchar uaAddr);
	int analyDatagram(int iIndexStep, char* pRecDataBuf, int iLen, CBattBank* pCurBattData);
	int analyComInputRegDatagram(char* pRecDataBuf, int iLen, quint16* pComInputRegData);
	int analyStackDatagram(char* pRecDataBuf, int iLen, CBattStack* pStack);
//	int prepareSetHoldDatagram(int iSetHoldRegStep, CBattStack* pStack, CBattBank* pBattBank, SAlarmParam* pAlarmParam, char* pSendDataBuf);// Hold Register
//	int analySetHoldReturnDatagram(char* pRecDataBuf, int iLen);
	int analyStackHoldDatagram(char* pRecDataBuf, int iLen, CBattStack* pStack); 

	// Data tran
	int analyReqDatagram(char* pDataBuf, int iLen, SMdobusTcpReq& req);
	int prepareBattDatagram(char* pDataBuf, SMdobusTcpReq* pReq, CBattBank* pBattBank);
	int prepareAlarmCacheDatagram(char* pDataBuf, SMdobusTcpReq* pReq, CBattBank* pBattBank, CBankAlarm* pBankAlarm);	
	int prepareStackDatagram(char* pDataBuf, SMdobusTcpReq* pReq, CBattStack* pBattStack);
	int prepareUpdateDatagram(char* pDataBuf, SMdobusTcpReq* pReq, CBattStack* pBattStack);
	int prepareBankAlarmDatagram(char* pDataBuf, SMdobusTcpReq* pReq, SAlarmParam* pAlarmParam, CBattBank* pBattBank, CBattStack* pBattStack);
	int prepareExcepDatagram(char* pDataBuf, SMdobusTcpReq* pReq, uchar uaExcepCode);	
	int prepareBAComInputRegDatagram(char* pDataBuf, SMdobusTcpReq* pReq, quint16* pComInputRegData);
	int prepareBAComHoldRegDatagram(char* pDataBuf, SMdobusTcpReq* pReq, quint16* pComHoldRegData);

	int getRegValStack(quint16 usRegAddr, CBattStack* pBattStack, quint16& usVal, float& fVal);
	int getRegValBank(quint16 usRegAddr, CBattBank* pBattBank, quint16& usVal, float& fVal, quint32& uiVal);
	int getRegValBankDis(quint16 usRegAddr, CBattBank* pBattBank);

	int addParam2Buffer(char* pData, quint32 uiParamVal);
	int addParam2Buffer(char* pData, quint16 uiParamVal);
	int addParam2Buffer(char* pData, float fParamVal);

	// RTU
	int addModbusCRC2Buffer(char *pData, int iLen);
	int analyDatagramRtuPCS(char *pData, int iLen);

private:
	int getParamFromBuffer(char* pData, quint16& uiParamVal);
	int getParamFromBuffer(char* pData, quint32& uiParamVal);
	int getParamFromBuffer(char* pData, float& fParamVal);

	int formDatagram(quint16 usEvent, uchar uaAddr, uchar uaFuncCode, quint16 usStartReg, quint16 usRegNum, char* pSendDataBuf);
	int formHoldRegDatagram(quint16 usEvent, uchar uaAddr, quint16 usStartReg, quint16 usRegNum, char* pSendDataBuf, float* pFVal);	

	void addRegVal2BufferBankDis(char* pData, quint16 usRegAddr, CBattBank* pBattBank);
	quint16 addRegVal2BufferBank(char* pData, quint16 usRegAddr, CBattBank* pBattBank);
	quint16 addRegVal2BufferStack(char* pData, quint16 usRegAddr, CBattStack* pBattStack);	
	quint16 addRegVal2BufferUpdate(char* pData, quint16 usRegAddr, CBattStack* pBattStack);	

	int setAlarmHoldRegVal(quint16 usRegAddr, quint16 usVal, SAlarmParam* pAlarmParam, CBattBank* pBattBank, CBattStack* pBattStack);
	int setStackHoldRegVal(quint16 usRegAddr, quint16 usVal, CBattStack* pBattStack);
	int setUpdateHoldRegVal(quint16 usRegAddr, quint16 usVal, CBattStack* pBattStack);
	int addHoldRegVal2BufferAlarm(char* pData, quint16 usRegAddr, SAlarmParam* pAlarmParam, CBattBank* pBattBank);
	int addHoldRegVal2BufferStack(char* pData, quint16 usRegAddr, CBattStack* pBattStack);
	int addHoldRegVal2BufferUpdate(char* pData, quint16 usRegAddr, CBattStack* pBattStack);

	quint16 Modbus_CRC16(char *pData, quint16 usLen);
};

#endif // MODBUSFACTORY_H
